<template>
    <div class="body-inner">
        <h1 class="body-title">
            <i :class="$bodyTitle.icon"></i>
            <span>{{ $bodyTitle.description }}</span>
        </h1>
        <div class="line10"></div>
        <div class="body-main">
            <div class="base64">
                <div class="resource">
                    <div class="message">
                        <textarea @input="message2base64" v-model="message" placeholder="输入原文"></textarea>
                    </div>
                    <label :for="uploadFileId" class="dragArea" :class="{dropActive:dropActive}" ref="dragArea">
                        <div class="icon appfont app-img-upload"></div>
                        <div class="title">拖动文件到此处，或点击上传</div>
                    </label>
                    <input :id="uploadFileId" type="file" :accept="accept" @change="getUploadBase64">
                </div>
                <div class="result">
                    <div class="btns">
                        <tips v-if="result" class="tips" :tip="`复制`" :direction="'top'">
                            <i @click="$copy(result)" class="copy appfont app-copy"></i>
                        </tips>
                        <tips v-if="result" class="tips" :tip="`清空`" :direction="'top'">
                            <i @click="clear" class="clear-res appfont app-clear"></i>
                        </tips>
                    </div>
                    <textarea @input="resultChange" v-model="result" placeholder="编码结果（支持填入base64转换为图片）"></textarea>

                    <!-- 分析结果 -->
                    <div class="panel" v-if="result">
                        <div class="info">
                            <div class="row" v-if="info.type">
                                <span>类型：</span>
                                <em>{{ info.type }}</em>
                            </div>
                            <div class="row" v-if="info.name">
                                <span>名称：</span>
                                <em>{{ info.name }}</em>
                            </div>
                            <div class="row" v-if="info.path">
                                <span>路径：</span>
                                <em>{{ info.path }}</em>
                            </div>

                            <button @click="saveImage" type="button" class="download" v-if="info.isImg && !info.path && !info.imgError">
                                保存图片
                            </button>
                            <div class="row" v-if="info.isImg && !info.path && !info.imgError">
                                <em>或拖动图片到指定位置保存</em>
                            </div>
                        </div>
                        <div class="thumb" v-if="info.isImg">
                            <tips class="tips" :tip="`拖动到桌面保存`" :direction="'top'">
                                <img v-if="!info.imgError" @error="info.imgError=true" @load="info.imgError=false" ref="thumb"
                                     draggable="true" :src="result" width="1">
                                <div v-else class="imgError">
                                    <i class="icon appfont app-img-error"></i>
                                    <p>图像解析失败</p>
                                </div>
                            </tips>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import { Base64 } from 'js-base64';
import IPC from '../../electron/ipc/dict';

/**
 * base64分析信息
 * @return {{path: string, isImg: boolean, name: string, type: string}}
 */
function base64Info () {
    return {
        isImg   : false,
        imgError: false,
        type    : '',
        name    : '',
        path    : ''
    };
}

export default {
    name: 'kit_base64',
    data () {
        return {
            dropActive  : false,
            uploadFileId: 'uploadFileId', /*文件上传域的id*/
            maxSize     : 10, /*单位M，最大上传尺寸*/
            accept      : '*',
            message     : '',
            result      : '',
            info        : base64Info(),
            fileTmp     : null
        };
    },
    mounted () {
        /*利用拖动获取文件base64*/
        this.getDropBase64();
    },

    watch  : {
        /*分析base64代码*/
        result (val) {
            if (!val) return;
            this.info = base64Info();

            /*字符串类型*/
            if (this.message) {
                this.info.type = '字符串';
                return;
            }

            /*分析上传文件*/
            if (this.fileTmp) {
                this.info.name = this.fileTmp.name;
                this.info.path = this.fileTmp.path;
            }

            /*匹配图片格式*/
            let res = /^data\:image\/(.*?);base64,/i.exec(val);

            /*图片*/
            if (res) {
                this.info.isImg = true;
                this.info.type  = `图片（${res[1].toUpperCase()}）`;
            }
            /*其他文件*/
            else {
                this.info.type = this.fileTmp ? '文件' : '未识别';
            }
        }
    },
    methods: {
        /**
         * 清空所有
         */
        clear () {
            this.resultChange();
            this.result = '';
        },

        /**
         * 保存文件
         */
        saveImage () {
            ipcRenderer.send(IPC.IPC_DIALOG.SAVE_FILE, { filter: 'Images', data: this.result });
            ipcRenderer.once(IPC.IPC_DIALOG.SAVE_FILE_RESULT, (e, data) => console.log(data));
        },

        /**
         * 结果框内容输入更新
         */
        resultChange () {
            /*清理文本框*/
            this.message = '';

            /*清理上传的文件对象缓存*/
            this.fileTmp = null;
        },

        /**
         * 文字转base64
         */
        message2base64 () {
            this.result = Base64.encode(this.message);

            /*清理上传的文件对象缓存*/
            this.fileTmp = null;
        },

        /**
         * 利用上传获取文件base64
         */
        getUploadBase64 (e) {
            /*清理文本框*/
            this.message = '';

            /*文件转base64*/
            this.file2base64(e.target.files);

            /*重置上传域*/
            let file   = document.getElementById(this.uploadFileId);
            file.value = '';
        },

        /**
         * 利用拖动获取文件base64
         */
        getDropBase64 () {
            /*清理文本框*/
            this.message = '';

            /*监听拖动*/
            const dragArea = this.$refs.dragArea;
            dragArea.addEventListener('drop', (e) => {
                this.dropActive = false;
                e.stopPropagation();
                e.preventDefault();

                /*文件转base64*/
                this.file2base64(e.dataTransfer.files);
            }, false);

            dragArea.addEventListener('dragleave', (e) => {
                this.dropActive = false;
                e.stopPropagation();
                e.preventDefault();
            });

            dragArea.addEventListener('dragenter', (e) => {
                this.dropActive = true;
                e.stopPropagation();
                e.preventDefault();
            });

            dragArea.addEventListener('dragover', (e) => {
                this.dropActive = true;
                e.stopPropagation();
                e.preventDefault();
            });
        },

        /*文件对象转base64*/
        file2base64 (files) {
            /*获取base64编码*/
            try {
                if (files.length <= 0) {
                    return;
                }

                if (files.length > 1) {
                    throw new Error('仅支持上传1个文件');
                }

                if (files[0].size > (this.maxSize * 1024 * 1024)) {
                    throw new Error(`文件尺寸不能超过 ${this.maxSize}M`);
                }

                /*记录已选文件*/
                this.fileTmp = files[0];

                let reader = new FileReader();
                reader.readAsDataURL(files[0]);
                reader.onload = () => this.result = reader.result;
            }
            catch (e) {
                this.$alert(e.message);
            }
        }
    }
};
</script>

<style scoped lang="less">
@dragAreaHeight : 175px;
.base64 {
    display         : flex;
    align-items     : center;
    justify-content : center;
    height          : calc(~"100vh - 125px");

    .resource {
        flex     : 1;
        height   : 100%;
        position : relative;

        .message {
            height                : 100%;
            -webkit-border-radius : 5px;
            -moz-border-radius    : 5px;
            border-radius         : 5px;
            background            : #fff;

            textarea {
                background            : #fff;
                border                : 0;
                -webkit-border-radius : 5px;
                -moz-border-radius    : 5px;
                border-radius         : 5px;
                width                 : 100%;
                height                : 100%;
                padding               : 15px;
                padding-bottom        : @dragAreaHeight + 30px;
            }
        }

        .dragArea {
            cursor                : pointer;
            position              : absolute;
            z-index               : 100;
            background            : rgba(238, 238, 238, 0.9);
            border                : 2px dashed #aaa;
            color                 : #000;
            height                : @dragAreaHeight;
            -webkit-border-radius : 6px;
            -moz-border-radius    : 6px;
            border-radius         : 6px;
            bottom                : 15px;
            left                  : 15px;
            width                 : calc(~"100% - 30px");
            display               : flex;
            justify-content       : center;
            align-items           : center;
            flex-direction        : column;

            &.dropActive {
                background : fade(@blue, 80%);
                border     : 2px dashed @blue;

                .icon {
                    color : #fff;
                }

                .title {
                    color : #fff;
                }
            }

            .icon {
                font-size : 50px;
                color     : #999;
            }

            .title {
                margin-top : 10px;
                color      : #999;
            }
        }

        [type=file] {
            display : none;
        }
    }

    .result {
        height      : 100%;
        flex        : 1;
        margin-left : 20px;
        position    : relative;

        .btns {
            position        : absolute;
            z-index         : 100;
            top             : 0;
            right           : 0;
            display         : flex;
            align-items     : center;
            justify-content : flex-end;

            .tips {
                display         : flex;
                align-items     : center;
                justify-content : center;
                margin-right    : 5px;

                &:last-child {
                    margin-right : 10px;
                }

                .copy, .clear-res {
                    margin-top            : 10px;
                    height                : 35px;
                    width                 : 35px;
                    display               : flex;
                    align-items           : center;
                    justify-content       : center;
                    color                 : #fff;
                    cursor                : pointer;
                    background            : rgba(180, 180, 180, 0.8);
                    -webkit-border-radius : 5px;
                    -moz-border-radius    : 5px;
                    border-radius         : 5px;

                    &:hover {
                        background : fade(@blue, 90%);
                        color      : #fff;
                    }
                }
            }
        }

        textarea {
            background            : #fff;
            border                : 0;
            -webkit-border-radius : 5px;
            -moz-border-radius    : 5px;
            border-radius         : 5px;
            width                 : 100%;
            height                : 100%;
            padding               : 15px;
            overflow-x            : hidden;
        }

        .panel {
            position              : absolute;
            z-index               : 100;
            bottom                : 15px;
            left                  : 15px;
            width                 : calc(~"100% - 30px");
            background            : #eee;
            border                : 2px dashed #aaa;
            -webkit-border-radius : 6px;
            -moz-border-radius    : 6px;
            border-radius         : 6px;
            color                 : #999;
            padding               : 20px;
            display               : flex;
            justify-content       : center;
            align-items           : center;

            .info {
                flex-grow   : 1;
                flex-shrink : 1;

                .row {
                    display       : flex;
                    margin-bottom : 6px;

                    &:last-child {
                        margin-bottom : 0;
                    }

                    span {
                        flex-grow   : 0;
                        flex-shrink : 0;
                    }

                    em {
                        flex-grow   : 1;
                        flex-shrink : 1;
                        color       : #333;
                    }
                }

                .download {
                    height                : 35px;
                    background            : @green;
                    color                 : #fff;
                    border                : 0;
                    margin-top            : 10px;
                    width                 : 160px;
                    -webkit-border-radius : 3px;
                    -moz-border-radius    : 3px;
                    border-radius         : 3px;
                    cursor                : pointer;
                    margin-bottom         : 10px;
                }
            }

            .thumb {
                margin-left : 20px;
                flex-grow   : 0;
                flex-shrink : 0;
                width       : 100px;
                height      : 100px;

                .tips {
                    width  : 100%;
                    height : 100%;
                }

                img, .imgError {
                    display    : block;
                    width      : 100%;
                    height     : 100%;
                    border     : 1px solid #ccc;
                    padding    : 3px;
                    background : #fff;
                    object-fit : cover;
                    cursor     : move;
                    position   : relative;
                }

                .imgError {

                    .icon {
                        position        : relative;
                        z-index         : 1;
                        width           : 100%;
                        height          : 100%;
                        display         : flex;
                        justify-content : center;
                        padding-top     : 25px;
                        font-size       : 50px;
                        color           : #999;
                        background      : #eee;
                    }

                    p {
                        position   : absolute;
                        width      : 100%;
                        bottom     : 25px;
                        z-index    : 2;
                        left       : 0;
                        text-align : center;
                    }
                }
            }
        }
    }
}
</style>
